package com.um.springboot.starter.event;

import com.um.springboot.starter.properties.RedisEventProperties;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * Redis分布式事件发布者
 *
 * @author 甘天伟
 * @since 2024/5/7
 * 版权所有 广州优匠科技有限公司
 */
@Slf4j
@Component
@ConditionalOnProperty("hsh.redis-event.publisher")
public class RedisEventPublisher {

    @Autowired
    private RedisEventProperties redisEventProperties;

    @Autowired
    private RedissonClient redissonClient;

    private RBlockingDeque<RedisEventItem> blockingDeque;

    private RDelayedQueue<RedisEventItem> delayedQueue;

    @PostConstruct
    private void init() {
        blockingDeque = redissonClient.getBlockingDeque(redisEventProperties.getQueueName());
        delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
    }

    /**
     * 发布事件
     *
     * @param event
     */
    public void publishEvent(RedisEvent event) {
        RedisEventItem item = new RedisEventItem(event);
        blockingDeque.offer(item);
        log.debug("发布事件: {}", item);
    }

    /**
     * 发布延迟事件
     *
     * @param event
     * @param delay
     * @param timeUnit
     */
    public void publishDelayedEvent(RedisEvent event, long delay, TimeUnit timeUnit) {
        RedisEventItem item = new RedisEventItem(event);
        delayedQueue.offer(item, delay, timeUnit);
        log.debug("发布延迟事件: {}", item);
    }

    /**
     * 移除事件
     *
     * @param event
     */
    public void removeEvent(RedisEvent event) {
        RedisEventItem item = new RedisEventItem(event);
        blockingDeque.remove(item);
        log.debug("移除事件: {}", item);
    }

    /**
     * 移除延迟事件
     *
     * @param event
     */
    public void removeDelayedEvent(RedisEvent event) {
        RedisEventItem item = new RedisEventItem(event);
        delayedQueue.remove(item);
        log.debug("移除延迟事件: {}", item);
    }
}
